<?php
class Component_Paypalpro_Pgateway_Paypalpro extends Component_Appstore_Helpers_Pgateway_Common
{
	const PAYMENT_SUCCESS_URL = '/payment-success';
	const STATUS_NAME = 'Paypalpro';
	const PAYMENT_ACTION = "Authorization";
	const API_ENDPOINT ='https://api-3t.sandbox.paypal.com/nvp';
	const PAYMENT_TYPE = 'doDirectPayment';
	const VERSION = 65.1;
	public function place()
	{
       $this->AssignPost()
			 ->Execute();
	}

	public function getStatusName()
	{
		return self::STATUS_NAME;
	}

	private function AssignPost()
	{
		$this->setXPaymentAction(self::PAYMENT_ACTION);

		$this->setXMethod(self::PAYMENT_TYPE)
			 ->setXVersion(self::VERSION)
			 ->setXPwd(App::Helper('Config')->siteInfo('paypalpro_password',false))
			 ->setXUser(App::Helper('Config')->siteInfo('paypalpro_username',false))
			 ->setXSignature(App::Helper('Config')->siteInfo('paypalpro_signature',false));

		$customer  = $this->getBillingAddress();
		$this->setXFirstName((isset($customer['fname'])?$customer['fname']:""))
			 ->setXLastName((isset($customer['lname'])?$customer['lname']:""))
			 ->setXAddress1((isset($customer['address_line_1'])?$customer['address_line_1']:""))
			 ->setXAddress2((isset($customer['address_line_2'])?$customer['address_line_2']:""))
			 ->setXState((isset($customer['city'])?$customer['city']:""))
			 ->setXState((isset($customer['state'])?$customer['state']:""))
			 ->setXCountry((isset($customer['country'])?$customer['country']:""))
			 ->setXZip((isset($customer['zipcode'])?$customer['zipcode']:""));

		$paymentData = $this->getPaymentData();
		$paymentData['CardNo'] = isset($paymentData['CardNo']) ? $paymentData['CardNo'] : "";
		$paymentData['cvv'] = isset($paymentData['cvv']) ? $paymentData['cvv'] : "";

		$CardType = (isset($paymentData['CardType']) ? $paymentData['CardType'] : 'visa');

		if(App::Helper('Validation')->cc($paymentData['CardNo'],Array('type'=>$CardType))){
			$this->setXCardNum($paymentData['CardNo']);
		}
		else{
			throw new AppException($this->__('Invalid credit card information'));
		}

		$month = $paymentData['expire_date']['month'];
		$year = $paymentData['expire_date']['year'];

		$this->setXCardType($CardType);
		$this->setXCvv($paymentData['cvv']);
		$this->setXExpDate("{$month}{$year}");


		if($this->getAmount()>0){
			$this->setXAmount($this->getAmount());
		}
		else
		{
			throw new AppException($this->__('Invalid amount changed'));
		}

		$this->setXCurrencyCode('USD');

		return $this;

	}

	public function Execute()
	{
		$post_values = array(
			"METHOD"		=> $this->getXMethod(),
			"VERSION"		=> $this->getXVersion(),
			"PWD"	=> $this->getXPwd(),
			"USER"	=> $this->getXUser(),
			"SIGNATURE"	=> $this->getXSignature(),


			"PAYMENTACTION"	=> $this->getXPaymentAction(),
			"CREDITCARDTYPE"=> $this->getXType(),
			"ACCT"			=> $this->getXCardNum(),
			"EXPDATE"		=> $this->getXExpDate(),
			"CVV2"			=> $this->getXCvv(),

			"AMT"			=> round($this->getXAmount(),2),

			"FIRSTNAME"		=> $this->getXFirstName(),
			"LASTNAME"		=> $this->getXLastName(),
			"STREET"		=> $this->getXAddress1(),
			"CITY"			=> $this->getXCity(),
			"STATE"			=> $this->getXState(),
			"ZIP"			=> $this->getXZip(),
			"COUNTRYCODE"	=> $this->getXCountry(),
			"CURRENCYCODE"	=> $this->getXCurrencyCode()
		);

		$post_string = "";
		foreach( $post_values as $key => $value ){ $post_string .= "$key=" . urlencode( $value ) . "&"; }
		$post_string = rtrim( $post_string, "& " );

        if(strtolower(App::Helper('Config')->siteInfo('paypalpro_mode',false)) == 'test')
        {
		    $request = curl_init(self::API_ENDPOINT); // initiate curl object
        }
        else
        {
            $request = curl_init('https://api-3t.paypal.com/nvp'); // initiate curl object
        }
		curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
		curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
		curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
		curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
		$post_response = curl_exec($request); // execute curl post and store results in $post_response
		curl_close ($request);

		$response = $this->deformatNVP($post_response);

		$ack = strtoupper($response["ACK"]);
		if($ack!="SUCCESS")
		{
			throw new AppException($this->__($response['L_LONGMESSAGE0']));
		}

	}

	public function deformatNVP($nvpstr)
	{

		$intial=0;
		$nvpArray = array();


		while(strlen($nvpstr)){
			//postion of Key
			$keypos= strpos($nvpstr,'=');
			//position of value
			$valuepos = strpos($nvpstr,'&') ? strpos($nvpstr,'&'): strlen($nvpstr);

			/*getting the Key and Value values and storing in a Associative Array*/
			$keyval=substr($nvpstr,$intial,$keypos);
			$valval=substr($nvpstr,$keypos+1,$valuepos-$keypos-1);
			//decoding the respose
			$nvpArray[urldecode($keyval)] =urldecode( $valval);
			$nvpstr=substr($nvpstr,$valuepos+1,strlen($nvpstr));
		 }
		return $nvpArray;
	}

    public function htmlToRender()
    {
        $cardTypes = array('visa'=>'Visa',"amex"=>"Amex","bankcard"=>"Bankcard","diners"=>"Diners","disc"=>"Disc","electron"=>"Electron","enroute"=>"Enroute","jcb"=>"JCB","maestro"=>"Maestro","mc"=>"Master Card","solo"=>"Solo","switch"=>"Switch","voyager"=>"Voyager");
        return App::Module("DataGrid")->clear()
                                       ->setDisplay('FormListing')
                                       ->addRow("Card No.",App::Helper('Html')->inputTag("data[Payment][paypalpro][CardNo]","Type Credit Card Numper",array("class"=>"input-small check_notdefault")))
                                       ->addRow("Card Type.",App::Helper('Html')->selectTag("data[Payment][paypalpro][CardType]",$cardTypes,"visa",array("class"=>"check_notempty")))
                                       ->addRow("Exp Date",App::Helper('Html')->ccExpireDate("data[Payment][paypalpro][expire_date]","",array("id"=>"expire_date")))
                                       ->addRow("CVV",App::Helper('Html')->inputTag("data[Payment][paypalpro][cvv]","Type Card Varification Number",array("class"=>"input-small check_notdefault")),"(Last 3 Digits on the back)")
                                       ->Render(true);

    }

    public function paymentStatus()
    {
        return Component_Appstore_Helpers_Data::STATUS_PENDING;
    }
}